- Declaration and Use of Arrays in Xi -
( 1)>double a[10][10]; ( 2)>int n=5; ( 3)>char b[3*n][n]; ( 4)>a[0][2]=1.0; ( 5)>print(a[0][1],a[0][2]); <double> 0 <double> 1Arrays in Xi are started by element zero and go to n-1. For more comfortability the above lines are equivalent to this:
( 6)>double a[10,10]; ( 7)int n=5; ( 8)>char b[3*n,n]; ( 9)>a[0,2]=1.0; ( 10)>print(a[0,1],a[0,2]); <double> 0 <double> 1To declare an array with undefined dimensions use commands like this:
( 11)>double c[];You can initialize an array by:
( 12)>u={ {1,2}, {4,5} ,{ 8,9} }; ( 13)>print(u); <dblarr> 1 2 4 5 8 9To get the dimensions of an array use the function size. Size itself has a int array as return value. The first entry of this array is the type code, encoded as shown in the table below.
Type code | Data size |
0 | complex |
1 | double |
2 | float |
3 | int |
4 | short |
5 | char |
The second entry gives the dimension of the array, the third is the total number of entries in the array and the following entries are the sizes of the corresponding dimensions.
( 14)>print(size(a),size(b)); <intarr> 1 2 100 10 10 <intarr> 5 2 75 15 5You can perform all mathematical operations in a similar way with scalar arguments. A few examples:
( 15)>double k[10]; ( 16)>print(k); <dblarr> 0 0 0 0 0 0 0 0 0 0 ( 17)>for (i=0; i<10; i++) k[i]=i; ( 18)>print(cos(k)); <dblarr> 1 0.54030231 -0.41614684 -0.9899925 -0.65364362 0.28366219 0.96017029 0.75390225 -0.14550003 -0.91113026 ( 19)>print(++k); <dblarr> 1 2 3 4 5 6 7 8 9 10 ( 20)>print(k+k,k*k); <dblarr> 2 4 6 8 10 12 14 16 18 20 <dblarr> 1 4 9 16 25 36 49 64 81 100The binary operators "+,-,*,/" and standard mathematical functions are working element by element (the unary operators "-,++,--" too). The binary "#" operator arranges the matrix (array) multiplication which is not limited to one or two dimensional arrays.
<dblarr> ( 21)>print(k#k); <dblarr> 385
The function darr returns a double-precision array with the specified dimensions and all entry is set to zero. Dincarr returns a double-precision array with the specified dimensions too but the entries are set to there "absolute" position in the array (memory).
( 22)>print(darr(2,4),dincarr(2,4)); <dblarr> 0 0 0 0 0 0 0 0 <dblarr> 0 1 2 3 4 5 6 7The analogous functions for the other numerical types are:
Type | set zero | increment |
complex | cpxarr | cpxincarr |
double | darr | dincarr |
float | farr | fincarr |
int | iarr | iincarr |
short | sarr | sincarr |
char | carr | cincarr |
Xi supports a few methods to manipulate array oriented data efficiently. I.e. a posible access to an array is
( 23)>q=dincarr(10)+1; ( 24)>print(q) <dblarr> 1 2 3 4 5 6 7 8 9 10 ( 25)>q[1:5:2]=0; ( 26)>print(q); <dblarr> 1 0 3 0 5 0 7 8 9 10In the experession q[1:5:2] the first value sets the startpoint, the second value fixes the endpoint an the third is the stepsize. Therefore line 25 is consequently equal to
( 27)>for (i=1; i<=5; i+=2) q[i]=0;To change the entries of a whole row of an array use the "*" access (best regards to PL/I;-)
( 28)>a=dincarr(2,4); ( 29)>a[0,*]=0; ( 30)>a[1,*]=sin(dincarr(4)) ( 31)>print(a); <dblarr> 0 0 0 0 0 0.84147098 0.90929743 0.14112001More complicated relations are imaginable.
( 32)>a=darr(5,5); ( 33)>a[1:3:2,*]=dincarr(2,5); ( 34)>print(a); <dblarr> 0 0 0 0 0 0 1 2 3 4 0 0 0 0 0 5 6 7 8 9 0 0 0 0 0A powerful tool for manipulating data is the "where" access to an array. Depending on a comparison the where command changes the entries of an array.
( 35)>a=dincarr(4,4); ( 36)>b=darr(4,4)+15; ( 37)>a[where(( a < 5) || (a == b) )]=255; ( 38)>print(a); <dblarr> 255 255 255 255 255 5 6 7 8 9 10 11 12 13 14 255
The function sum allows you to take the sum over some directions of an array.
( 39)>print(sum(dincarr(10,10),0)); <dblarr> 450 460 470 480 490 500 510 520 530 540 ( 40)>print(sum(dincarr(10,10),1,0)); <dblarr> 4950Also to get the total sum over all indices type
( 41)>print(total(dincarr(10,10))); <double> 4950Maximum, minimum and the position of a extrema in an array can be obtained by
( 42)>a=dincarr(10,10); ( 43)>print(max(a), min(a), locate_min(a), locate_max(a)); <double> 99 <double> 0 <intarr> 0 0 <intarr> 9 9
Lets assume that you have an array with n dimensions. To replicate this array m times to get an array with n+1 dimensions type
( 44)>b=dincarr(3,3); ( 45)>print(replicate(a,2)); <dblarr> 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8The function histogram returns the density of an array. The parameter \binsize specifies the size of the bins.
( 46)>a={5,16,13,-4,6,5,12,2,3,5}; ( 47)>[h,x]=histogram(a,\binsize=2);The array h contains the density of array a at the locations described in x.
Xi stores the data of a multidimensional array in the same way C does. Maybe sometime you want to modify the dimensions of an array without changing its values (that means without changing the memory that Xi use for the array). Such an operation can be done with the reshape function of Xi
( 48)>a=dincarr(3,3); ( 49)>print(a) <dblarr> 0 1 2 3 4 5 6 7 8 ( 50)>b=reshape(a,9); ( 51)>print(b); <dblarr> 0 1 2 3 4 5 6 7 8To avoid memory garbage the total number of elements have to be left unchanged.
Xi supports algortihms to resize a multidimensional array.
To magnify or shrink an array by nearest neigbourhood sampling use
The shift function shifts the entries of an array along a number of elements
using periodic boundary conditions.
( 52)>a=dincarr(10);
( 53)>print(a,resize(a,5,\sample));
<dblarr>
0 1 2 3 4 5 6 7 8 9
<dblarr>
1 3 5 7 9
( 54)>a=dincarr(3,3);
( 55)>print(a,resize(a,10,10));
<dblarr>
0 1 2
3 4 5
6 7 8
<dblarr>
0 0 1 2 2
0 0 1 2 2
3 3 4 5 5
6 6 7 8 8
6 6 7 8 8
It is also possible to perform the resampling by the so called
multilinear interpolation method. This method gives higher quality results
but requires more CPU-time as the nearst neigbbourhood sampling. Comparing
with spline interpolation or spectral analysis it is a fast algorithm and
frequently "close enough for government work".
( 56)>a=dincarr(5);
( 57)>print(a,resize(a,10,\linear));
<dblarr>
0 1 2 3 4
<dblarr>
0.2 0.6 1 1.4 1.8 2.2 2.6 3 3.4 3.8
< 58)>print(a,shift(a,1),shift(a,2));
<dblarr>
0 1 2 3 4
<dblarr>
1 2 3 4 0
<dblarr>
2 3 4 0 1
( 59)>print(shift(dincarr(4,4),1,1));
<dblarr>
5 6 7 4
9 10 11 8
13 14 15 12
1 2 3 0
Another useful routine is the dist function. The result is a multidimensional
array. Each entry corresponds to the square distance to the center of the array.
( 60)>print(dist(5)); <dblarr> 4 1 0 1 4 ( 61)>print(dist(5,5)); <dblarr> 8 5 4 5 8 5 2 1 2 5 4 1 0 1 4 5 2 1 2 5 8 5 4 5 8